package com.dzl.aliyunoss;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

public class ALiYunOSSUtis {

    private static final Logger logger = LoggerFactory.getLogger(ALiYunOSSUtis.class);

    /**
     * 获取阿里云OSS客户端对象
     */
    public static final OSSClient getOSSClient(String endpoint ){
        return new OSSClient(endpoint ,ALiYunOSSConstant.OSS_ACCESS_KEY_ID,ALiYunOSSConstant.OSS_ACCESS_KEY_SECRET);
    }

    /**
     * @Description:TODO
     * @param endpoint 		   服务地址
     * @param uploadFile
     * @param uploadFileName
     * @param bucketName
     * @return
     * String
     * @exception:
     * @author: hemiao
     * @time:2017年4月24日 上午11:23:22
     */
    public static String uploadALiYunOssFile(String endpoint ,String uploadFile,String uploadFileName,String bucketName){

        OSSClient ossClient = getOSSClient(endpoint );

    	String OssUploadFileName = uploadFileName+"."+uploadFile.substring(uploadFile.lastIndexOf(".")+1);
        try {

            UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, OssUploadFileName);

            // 待上传的本地文件
            uploadFileRequest.setUploadFile(uploadFile);

            // 设置并发下载数，默认1
            uploadFileRequest.setTaskNum(5);
            // 设置分片大小，默认100KB
            uploadFileRequest.setPartSize(1024 * 1024 * 1);
            // 开启断点续传，默认关闭
            uploadFileRequest.setEnableCheckpoint(true);
            // 创建上传Object的Metadata
            ObjectMetadata meta = new ObjectMetadata();

            //根据文件的后缀名 设置 上传文件ContentType 类型  否则无法直接访问
            meta.setContentType(getcontentType(uploadFile));
            //meta.setContentType("image/jpeg");
            //meta.setContentType("video/mp4");
            uploadFileRequest.setObjectMetadata(meta);

            UploadFileResult uploadResult = ossClient.uploadFile(uploadFileRequest);

            CompleteMultipartUploadResult multipartUploadResult = uploadResult.getMultipartUploadResult();
            System.out.println(multipartUploadResult.getETag());

        } catch (OSSException oe) {
            logger.error("错误消息: " + oe.getErrorCode()+";错误代码: " + oe.getErrorCode()+";请求ID:  " + oe.getRequestId()+";主机ID:  " + oe.getHostId());
        } catch (ClientException ce) {
            logger.error("ALiYunOss通讯异常："+ce.getMessage());
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
        }
    	return OssUploadFileName;
    }

    /**
     * @Description:通过文件全名得到文件的访问rul;并且设置该url的访问超时时间
     * @param fileName
     * @return
     * String
     * @exception:
     * @author: hemiao
     * @time:2017年4月13日 上午10:37:48
     */
    public static String getALiYunOssPrivateFileUrl(String endpoint,String bucketName,String fileName){
    	OSSClient ossClient = getOSSClient(endpoint);

    	//图片处理样式
	    //String style = "image/resize,m_fixed,w_600,6_100/rotate ,0";

	    //访问资源url过期时间30分钟
	    Date expiration = new Date(System.currentTimeMillis() + 1000 * 60 * 30 );

	    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName,fileName);
	    //req.setProcess(style);
	    request.setExpiration(expiration);
	    URL signedUrl = ossClient.generatePresignedUrl(request);
    	return String.valueOf(signedUrl);
    }

      /**
       * @Description:判断OSS服务文件上传时文件的contentType
       * @param str
       * @return
       * String
       * @exception:
       * @author: hemiao
       * @time:2017年4月13日 上午10:37:33
       */
	  public static String getcontentType(String str){
	      String prefix=str.substring(str.lastIndexOf(".")+1);
	      if("jpg".equals(prefix)){
	    	  return "image/jpeg";
	      }
		  if("mp4".equals(prefix)){
			  return "video/mp4";
		  }
		 return "1";
	  }

	  /**
	   * @Description:设置访问权限 Bucket属性
	   * @param client
	   * @param bucketName
	   * @param acl
	   * void
	   * @exception:
	   * @author: hemiao
	   * @time:2017年4月13日 上午10:37:01
	   */
	  public static void createBucket(OSSClient client, String bucketName,
			  CannedAccessControlList acl) {
		  //key1创建名为saas01的BUCKET，权限为私有
		  //createBucket(ossClient, "saas01", CannedAccessControlList.Private);

		  // key2创建名为saas02的BUCKET，权限为公用读写
		  //createBucket(ossClient, "saas02", CannedAccessControlList.PublicReadWrite);

		  // key1创建名为saas03的BUCKET，权限为公用读
		  //createBucket(ossClient, "saas03", CannedAccessControlList.PublicRead);

	      //通过一个Bucket对象来创建	构造函数入参为Bucket名称，可以为空
	      CreateBucketRequest bucketObj = new CreateBucketRequest(null);
	      //设置bucketObj名称
	      bucketObj.setBucketName(bucketName);
	      //设置bucketObj访问权限acl
	      bucketObj.setCannedACL(acl);
	      //创建Bucket
	      client.createBucket(bucketObj);
	  }

    /**
     * 新建Bucket  --Bucket权限:私有
     * @param bucketName bucket名称
     * @return true 新建Bucket成功
     */
    public static final boolean createBucket(OSSClient client, String bucketName){
        Bucket bucket = client.createBucket(bucketName);
        return bucketName.equals(bucket.getName());
    }

    /**
     * 删除Bucket
     * @param bucketName bucket名称
     */
    public static final void deleteBucket(OSSClient client, String bucketName){
        client.deleteBucket(bucketName);
        logger.info("删除" + bucketName + "Bucket成功");
    }

    /**
     * 向阿里云的OSS存储中存储文件  --file也可以用InputStream替代
     * @param client OSS客户端
     * @param file 上传文件
     * @param bucketName bucket名称
     * @param diskName 上传文件的目录  --bucket下文件的路径
     * @return String 唯一MD5数字签名
     */
    public static final String uploadObject2OSS(OSSClient client, File file, String bucketName, String diskName) {
        String resultStr = null;
        try {
            InputStream is = new FileInputStream(file);
            String fileName = file.getName();
            Long fileSize = file.length();
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(is.available());
            metadata.setCacheControl("no-cache");
            metadata.setHeader("Pragma", "no-cache");
            metadata.setContentEncoding("utf-8");
            metadata.setContentType(getContentType(fileName));
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            //上传文件
            PutObjectResult putResult = client.putObject(bucketName, diskName + fileName, is, metadata);
            //解析结果
            resultStr = putResult.getETag();
        } catch (Exception e) {
            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return resultStr;
    }

    /**
     * 根据key获取OSS服务器上的文件输入流
     * @param client OSS客户端
     * @param bucketName bucket名称
     * @param diskName 文件路径
     * @param key Bucket下的文件的路径名+文件名
     */
     public static final InputStream getOSS2InputStream(OSSClient client, String bucketName, String diskName, String key){
        OSSObject ossObj = client.getObject(bucketName, diskName + key);
        return ossObj.getObjectContent();
     }

   /**
    * 根据key删除OSS服务器上的文件
    * @param client OSS客户端
    * @param bucketName bucket名称
    * @param diskName 文件路径
    * @param key Bucket下的文件的路径名+文件名
    */
	public static void deleteFile(OSSClient client, String bucketName, String diskName, String key){
		client.deleteObject(bucketName,key);
	    logger.info("删除" + bucketName + "下的文件" + diskName + key + "成功");
	}

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     * @param fileName 文件名
     * @return 文件的contentType
     */
     public static final String getContentType(String fileName){
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        if("bmp".equalsIgnoreCase(fileExtension)) return "image/bmp";
        if("gif".equalsIgnoreCase(fileExtension)) return "image/gif";
        if("jpeg".equalsIgnoreCase(fileExtension) || "jpg".equalsIgnoreCase(fileExtension)  || "png".equalsIgnoreCase(fileExtension) ) return "image/jpeg";
        if("html".equalsIgnoreCase(fileExtension)) return "text/html";
        if("txt".equalsIgnoreCase(fileExtension)) return "text/plain";
        if("vsd".equalsIgnoreCase(fileExtension)) return "application/vnd.visio";
        if("ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) return "application/vnd.ms-powerpoint";
        if("doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) return "application/msword";
        if("xml".equalsIgnoreCase(fileExtension)) return "text/xml";
        return "text/html";
     }

}
